Merge "rdbms: make LBFactory close/rollback dangling handles like LoadBalancer"
[lhc/web/wiklou.git] / includes / libs / rdbms / database / DatabaseSqlite.php
index cb1b842..8d417e6 100644 (file)
@@ -68,21 +68,21 @@ class DatabaseSqlite extends Database {
         *   - dbDirectory : directory containing the DB and the lock file directory
         *   - dbFilePath  : use this to force the path of the DB file
         *   - trxMode     : one of (deferred, immediate, exclusive)
-        * @param array $p
+        * @param array $params
         */
-       public function __construct( array $p ) {
-               if ( isset( $p['dbFilePath'] ) ) {
-                       $this->dbPath = $p['dbFilePath'];
-                       if ( !strlen( $p['dbname'] ) ) {
-                               $p['dbname'] = self::generateDatabaseName( $this->dbPath );
+       public function __construct( array $params ) {
+               if ( isset( $params['dbFilePath'] ) ) {
+                       $this->dbPath = $params['dbFilePath'];
+                       if ( !strlen( $params['dbname'] ) ) {
+                               $params['dbname'] = self::generateDatabaseName( $this->dbPath );
                        }
-               } elseif ( isset( $p['dbDirectory'] ) ) {
-                       $this->dbDir = $p['dbDirectory'];
+               } elseif ( isset( $params['dbDirectory'] ) ) {
+                       $this->dbDir = $params['dbDirectory'];
                }
 
-               parent::__construct( $p );
+               parent::__construct( $params );
 
-               $this->trxMode = strtoupper( $p['trxMode'] ?? '' );
+               $this->trxMode = strtoupper( $params['trxMode'] ?? '' );
 
                $lockDirectory = $this->getLockFileDirectory();
                if ( $lockDirectory !== null ) {
@@ -96,7 +96,10 @@ class DatabaseSqlite extends Database {
        }
 
        protected static function getAttributes() {
-               return [ self::ATTR_DB_LEVEL_LOCKING => true ];
+               return [
+                       self::ATTR_DB_IS_FILE => true,
+                       self::ATTR_DB_LEVEL_LOCKING => true
+               ];
        }
 
        /**
@@ -142,7 +145,12 @@ class DatabaseSqlite extends Database {
                        throw $this->newExceptionAfterConnectError( "DB path or directory required" );
                }
 
-               if ( !self::isProcessMemoryPath( $path ) && !is_readable( $path ) ) {
+               // Check if the database file already exists but is non-readable
+               if (
+                       !self::isProcessMemoryPath( $path ) &&
+                       file_exists( $path ) &&
+                       !is_readable( $path )
+               ) {
                        throw $this->newExceptionAfterConnectError( 'SQLite database file is not readable' );
                } elseif ( !in_array( $this->trxMode, self::$VALID_TRX_MODES, true ) ) {
                        throw $this->newExceptionAfterConnectError( "Got mode '{$this->trxMode}' for BEGIN" );
@@ -163,6 +171,7 @@ class DatabaseSqlite extends Database {
                }
 
                try {
+                       // Open the database file, creating it if it does not yet exist
                        $this->conn = new PDO( "sqlite:$path", null, null, $attributes );
                } catch ( PDOException $e ) {
                        throw $this->newExceptionAfterConnectError( $e->getMessage() );
@@ -263,28 +272,6 @@ class DatabaseSqlite extends Database {
                return preg_match( '/^(:memory:$|file:(:memory:|[^?]+\?mode=memory(&|$)))/', $path );
        }
 
-       /**
-        * Check if the searchindext table is FTS enabled.
-        * @return bool False if not enabled.
-        */
-       public function checkForEnabledSearch() {
-               if ( self::$fulltextEnabled === null ) {
-                       self::$fulltextEnabled = false;
-                       $table = $this->tableName( 'searchindex' );
-                       $res = $this->query(
-                               "SELECT sql FROM sqlite_master WHERE tbl_name = '$table'",
-                               __METHOD__,
-                               self::QUERY_IGNORE_DBO_TRX
-                       );
-                       if ( $res ) {
-                               $row = $res->fetchRow();
-                               self::$fulltextEnabled = stristr( $row['sql'], 'fts' ) !== false;
-                       }
-               }
-
-               return self::$fulltextEnabled;
-       }
-
        /**
         * Returns version of currently supported SQLite fulltext search module or false if none present.
         * @return string
@@ -451,6 +438,36 @@ class DatabaseSqlite extends Database {
                return false;
        }
 
+       protected function doSelectDomain( DatabaseDomain $domain ) {
+               if ( $domain->getSchema() !== null ) {
+                       throw new DBExpectedError(
+                               $this,
+                               __CLASS__ . ": domain '{$domain->getId()}' has a schema component"
+                       );
+               }
+
+               $database = $domain->getDatabase();
+               // A null database means "don't care" so leave it as is and update the table prefix
+               if ( $database === null ) {
+                       $this->currentDomain = new DatabaseDomain(
+                               $this->currentDomain->getDatabase(),
+                               null,
+                               $domain->getTablePrefix()
+                       );
+
+                       return true;
+               }
+
+               if ( $database !== $this->getDBname() ) {
+                       throw new DBExpectedError(
+                               $this,
+                               __CLASS__ . ": cannot change database (got '$database')"
+                       );
+               }
+
+               return true;
+       }
+
        /**
         * Use MySQL's naming (accounts for prefix etc) but remove surrounding backticks
         *
@@ -765,6 +782,8 @@ class DatabaseSqlite extends Database {
        }
 
        public function serverIsReadOnly() {
+               $this->assertHasConnectionHandle();
+
                $path = $this->getDbFilePath();
 
                return ( !self::isProcessMemoryPath( $path ) && !is_writable( $path ) );